home *** CD-ROM | disk | FTP | other *** search
- /* troute.rexx - a very stupid traceroute */
-
- signal on break_c
-
- l="rmh.library";if ~show("L",l) then;if ~addlib(l,0,-30) then exit
- prg=ProgramName("NOEXT")
- if AddLibrary("rexxsupport.library","rxsocket.library","rxlibnet.library")~=0 then call err strings.ERRCANTFIND "'"result"'",1
-
- if ~RMH_ReadArgs("HOST/A") then do
- call PrintFault()
- exit
- end
-
- remote.addraddr=resolve(parm.0.value)
- if remote.addraddr=-1 then call err "host not found <"parm.0.value">",1
-
- us=socket("INET","DGRAM")
- if us<0 then call err "can't create udp socket"
- is=socket("INET","RAW","ICMP")
- if us<0 then call error "can't create icmp socket"
-
- secs=3
- tm=CreateTimer()
- ts=TimerSignal(tm)
-
- uss=2**AllocSignal()
- call IOCtlSocket(us,"FIOASYNC",1)
- call SetSockOpt(us,"SOCKET","EVENTMASK","READ ERROR")
-
- iss=2**AllocSignal()
- call IOCtlSocket(is,"FIOASYNC",1)
- call SetSockOpt(is,"SOCKET","EVENTMASK","READ ERROR")
-
- call SetSocketBaseSingle("SIGEVENTMASK",or(uss,iss))
-
- hope=3
- ttl=1
- baseport=30000
- mask=or(2**12,uss,iss,ts)
- stop=0
- do i=1 while ~stop
-
- remote.addrport=baseport
- call SetSockOpt(us,"IP","TTL",ttl)
- do hope=0 to 2
- if sendto(us," ",0,"REMOTE")<0 then call err "error sendto"
- srec=Wait(mask)
- if and(srec,ts)==0 then do
- if and(srec,2**12)>0 then call break_c
- if and(srec,or(iss,uss))>0 then res=getEv()
- do while res~=""
- say right(i,3) res
- hope=3
- if res==remote.addraddr then exit
- res=getEv()
- end
- end
- else call writech(stdout,"* ")
- call StartTimer(tm,3)
- end
- ttl=ttl+1
- end
- exit
-
- err: procedure expose prg
- parse arg msg,ntdoerr
- if ntdoerr~=1 then msg = msg "("ErrorString()")"
- say prg":" msg
- exit
-
- break_c:
- call err "interrputed",1
-
- getEv:
- s=GetSocketEvents("EV")
- do while s>=0
- if s=0 then call udpErr(ev.error,ev.read)
- if ev.read then return parseICMP()
- s=GetSocketEvents("EV")
- end
- return ""
-
- udpErr: procedure
- parse arg e,r
- if e then call err "error on udp"
- else call err "port is listening, better change it",1
-
- parseICMP:
- if recvfrom(is,"BUF",256)<0 then call err "error receiving"
- parse var buf iph +20 t +1 c +1 dummy +6 ipo +20
- if c2d(t)~=11 then
- if c2d(t)~=3 | c2d(c)~=3 then call err "bad icmp answer type:"c2d(t) "code:"c2d(c),1
- call readIP(ipo,"IPH")
- oid=iph.id
- call readIP(iph,"IPH")
- return iph.src
-
- call readICMP(BUF,"ICMP")
- if icmp.type~=3 then return ""
- if icmp.code~=3 then return ""
- parse var buf addr +4
- say c2x(buf)
- return inetntoa(c2d(addr))
-
-